<template>
	<view :class="pageClass" :style="pageStyle" v-if="pageReady" style="background-color: #F5F5F5; padding: 0 8px;">
		<moxi-nav :set="navSet"></moxi-nav>
		<view class="clock-records" :style="{ '--app-color': app_color, '--app-radius': '8px' }">
			<!-- 个人信息 -->
			<view class="person-info">
				<view class="avatar">
					<image style="width: 48px; height: 48px;" :src="userinfo.pic" mode="widthFix" />
				</view>
				<view class="info">
					<view class="name u-line-1">{{ userinfo.showname }}</view>
				</view>
				<!-- <view>{{ month }}月累计打卡{{ sumDay() }}天</view> -->
			</view>
			<!-- 日历 -->
			<view class="calendar">
				<!-- 日期 -->
				<view class="calendar_top">
					<u-icon name="arrow-left" @click="dateUp" color="#000"></u-icon>
					<view class="date">{{ year }}年{{ month }}月</view>
					<u-icon name="arrow-right" @click="dateDown"
						:color="disableRightClick ? '#AFAFAF' : '#000'"></u-icon>
				</view>
				<!-- 星期 -->
				<view class="week">
					<view class="item" v-for="(item, index) in calendarData" v-if="index < 7" :key="index">{{ item.label
					}}</view>
				</view>
				<view class="day" v-if="calendarData.length > 8">
					<view class="item" v-for="(item, index) in calendarData" v-if="index > 6" :key="index">
						<view @click="getInfo(item, index)" class="number" :class="index == activeIndex ? 'active' : ''"
							:style="{ 'color': item.color ? item.color : app_color, }">
							<view>{{ item.label }}</view>
							<!-- 正常打卡 -->
							<view class="badge" style="background-color: var(--app-color);"
								v-if="(item.type == 0 || item.type == 3) && item.status == 1 && (item.early == 0 && item.late == 0)">
							</view>
							<!-- 打卡异常 -->
							<!-- 缺卡 -->
							<view class="badge" style="background-color: #FF8B01;"
								:style="{ 'display': activeIndex == index ? 'none' : 'block', }"
								v-if="(item.type == 0 || item.type == 3) && item.status != 1 && item.date">
							</view>
							<!-- 下班早退 或 上班迟到 -->
							<view class="badge" style="background-color: #FF8B01;"
								:style="{ 'display': activeIndex == index ? 'none' : 'block', }"
								v-if="(item.type == 0 || item.type == 3) && item.status == 1 && (item.early != 0 || item.late != 0)">
							</view>
							<!-- 请假 -->
							<view class="badge_text" v-if="item.type == 4"
								:style="{ 'display': activeIndex == index ? 'none' : 'block', }">假
							</view>
							<!-- 调 -->
							<view class="badge_text" v-if="item.type == 3"
								:style="{ 'display': activeIndex == index ? 'none' : 'block', }">调
							</view>
							<!-- 节假日 -->
							<view class="badge_text" v-if="item.type == 2"
								:style="{ 'display': activeIndex == index ? 'none' : 'block', }">节
							</view>
							<!-- 休 -->
							<view class="badge_text" v-if="item.type == 1"
								:style="{ 'display': activeIndex == index ? 'none' : 'block', }">休
							</view>
						</view>
					</view>
				</view>
			</view>
			<!-- 展示状态 -->
			<view class="show-status" v-if="calendarData[activeIndex].type || calendarData[activeIndex].date">
				<view class="illustrate">
					<view class="item"
						v-if="(calendarData[activeIndex].type == 3 || calendarData[activeIndex].type == 0) && calendarData[activeIndex].status == 1 && calendarData[activeIndex].late == 0 && calendarData[activeIndex].early == 0">
						<view class="badge" style="background-color: var(--app-color)"></view>
						<view>全天考勤正常</view>
					</view>
					<view class="item"
						v-if="(calendarData[activeIndex].type == 3 || calendarData[activeIndex].type == 0) && (calendarData[activeIndex].status == 0 || calendarData[activeIndex].late != 0 || calendarData[activeIndex].early != 0)">
						<view class="badge" style="background-color: #FF8B01;"></view>
						<view>当天考勤存在异常: 迟到、早退、缺卡...</view>
					</view>
					<view class="item" v-if="calendarData[activeIndex].type && calendarData[activeIndex].type == 4">
						<view class="badge" style="background-color: #EA2121;"></view>
						<view>当日已请假</view>
					</view>
					<view class="item" v-if="calendarData[activeIndex].type && calendarData[activeIndex].type == 2">
						<view class="badge" style="background-color: #02CD68;"></view>
						<view>节假日，无需打卡</view>
					</view>
					<view class="item" v-if="calendarData[activeIndex].type && calendarData[activeIndex].type == 1">
						<view class="badge" style="background-color: #02CD68;"></view>
						<view>非工作日，无需打卡</view>
					</view>
				</view>

				<view class="showInfo"
					v-if="calendarData[activeIndex].type == 0 || (calendarData[activeIndex].type == 3)">
					<view class="go-line"
						v-if="calendarData[activeIndex].type == 0 || (calendarData[activeIndex].type == 3)">
						<view class="circle"
							:style="{ 'border-color': calendarData[activeIndex].late == 0 ? 'var(--app-color)' : '#FF8B01' }">
						</view>
						<view class="line"></view>
						<view class="circle"
							:style="{ 'border-color': calendarData[activeIndex].early == 0 ? 'var(--app-color)' : '#FF8B01' }">
						</view>
					</view>
					<view class="item go">
						<view class="go-item">
							<view class="title">
								<view style="margin-right: 8px;">上班打卡:</view>
								<view style="margin-right: 8px;">{{ calendarData[activeIndex].start ?
									calendarData[activeIndex].start : infoData.work_start }} </view>
								<view class="tag"
									v-if="calendarData[activeIndex].go && calendarData[activeIndex].go != 0"
									:style="{ 'background-color': calendarData[activeIndex].late == 0 ? 'var(--app-color)' : '#FF8B01', 'color': '#fff', }">
									{{ calendarData[activeIndex].late == 0 ? '正常' : '迟到' }}
								</view>
							</view>
							<view class="gotime"
								:style="{ 'color': calendarData[activeIndex].late == 0 ? 'var(--app-color)' : '#FF8B01' }">
								<view style="margin-right: 8px;">打卡时间:</view>
								<view v-if="calendarData[activeIndex].go && calendarData[activeIndex].go != 0">{{
									timestampToTime(calendarData[activeIndex].gotime) }}</view>
								<view v-else>未打卡</view>
							</view>
							<!-- <view class="wifi">
								<u-icon name="wifi"></u-icon>
								<view>moxicn</view>
							</view> -->
						</view>
						<view class="go-item">
							<view class="title">
								<view style="margin-right: 8px;">下班打卡:</view>
								<view style="margin-right: 8px;">{{ calendarData[activeIndex].end ?
									calendarData[activeIndex].end : infoData.work_end }}</view>
								<view class="tag"
									v-if="calendarData[activeIndex].off && calendarData[activeIndex].off != 0"
									:style="{ 'background-color': calendarData[activeIndex].early == 0 ? 'var(--app-color)' : '#FF8B01', 'color': '#fff', }">
									{{ calendarData[activeIndex].early == 0 ? '正常' : '早退' }}
								</view>
							</view>
							<view class="gotime"
								:style="{ 'color': calendarData[activeIndex].early == 0 ? 'var(--app-color)' : '#FF8B01' }">
								<view style="margin-right: 8px;">打卡时间:</view>
								<view v-if="calendarData[activeIndex].off && calendarData[activeIndex].off != 0">{{
									timestampToTime(calendarData[activeIndex].offtime) }}</view>
								<view v-else>未打卡</view>
							</view>
							<!-- <view class="wifi">
								<u-icon name="wifi"></u-icon>
								<view>moxicn</view>
							</view> -->
						</view>
					</view>
				</view>
			</view>
		</view>
		<moxi-tabbar :set="tabbar" v-if="tabbar.index_id"></moxi-tabbar>
	</view>
</template>

<script>
export default {
	data() {
		return {
			calendarData: [
				{ label: "日" },
				{ label: "一" },
				{ label: "二" },
				{ label: "三" },
				{ label: "四" },
				{ label: "五" },
				{ label: "六" },
			], //日历循环渲染数据
			year: 0,
			month: 0,
			week: -1,
			day: 0,
			activeIndex: 0,
			infoData: {
				"work_start": "", // 上班时间
				"work_end": "", // 下班时间
				"week": [],
				"must_clock": [],
				"no_clock": []
			},
			weekFormat: 'sunFirst', // 新增变量，'sunFirst' 表示日开头，'monFirst' 表示一开头
			info: {},
			// 打卡记录

			recordsList: [], // 打卡记录列表
			disableRightClick: false, // 控制点击事件
			fristLoad: true,
		};
	},
	mounted() {
		this.disableRightClickFun(); // 初始化禁用右点击事件
	},
	onLoad() {
		// 获取当前日期数据
		this.getNow();
		// go: 上班打卡状态 0 未打卡 1 打卡 2 异常, off: 下班打卡状态 0 未打卡 1 打卡 2 异常, gotime: 上班打卡时间, offtime: 下班打卡时间, type: 0 上班 1 周末 2 节假日 3 调休
		// 获取公司信息
		this.moxiPost(
			'/plugin/oa/user/clockin/getsetting', (res) => {
				this.infoData = res.data;
				this.getRecordsList(); // 获取打卡记录列表
			}
		);
	},
	methods: {
		disableRightClickFun() {
			// 只能查询到当天这个月之前
			let date = new Date();
			let nowYear = date.getFullYear();
			let nowMonth = date.getMonth() + 1;
			if (this.year === nowYear && this.month === nowMonth) {
				this.disableRightClick = true;
				return true;
			}
		},
		sumDay() {
			// 初始化公司工作日星期数组
			let sumDay = 0;
			let weekArray = [];
			for (let i = 0; i < this.infoData.week.length; i++) {
				weekArray.push(parseInt(this.infoData.week[i]));
			}
			// 统计累计打卡天数
			// 计算工作日打了多少天的卡
			this.recordsList.forEach(item => {
				// 时间戳 s 转换 2025-05-01 格式
				const date = new Date(item.work_start * 1000);
				const year = date.getFullYear();
				const month = date.getMonth() + 1;
				const day = date.getDate().toString().padStart(2, '0');
				month.toString().padStart(2, '0');
				const dateStr = `${year}-${month}-${day}`;
				this.infoData.must_clock.forEach(() => {
					// 调休打卡，则不算调休
					if (this.infoData.must_clock.includes(dateStr)) sumDay--;
				})
				sumDay++;
			})
			// 如果工作日当天为休息no_clock, 则算入
			this.infoData.no_clock.forEach(dateStr => {
				const date = new Date(dateStr);
				const year = date.getFullYear();
				const month = date.getMonth() + 1;
				const week = date.getDay();
				if (weekArray.includes(week) && year === this.year && month === this.month) {
					sumDay++;
				}
			});
			return sumDay;
		},
		// 时间戳 s 转换 9:00:00 格式
		timestampToTime(timestamp) {
			let date = new Date(timestamp * 1000);
			let hours = date.getHours().toString().padStart(2, '0');
			let minutes = date.getMinutes().toString().padStart(2, '0');
			let seconds = date.getSeconds().toString().padStart(2, '0');
			return `${hours}:${minutes}:${seconds}`;
		},
		// 工作日判断打卡 true 当天需要打卡 false 当天不需要打卡
		workDay(dateStr, work) {
			if (work > 0) { // 请假
				return 4;
			}

			// 先判断 当天日期 == this.infoData.must_clock 需要打卡
			if (this.infoData.must_clock.includes(dateStr)) {
				return 3;
			}
			// 再判断 当天日期 == this.infoData.no_clock 不需要打卡
			if (this.infoData.no_clock.includes(dateStr)) {
				return 2;
			}
			// 获取当前时间周几 1 2 3 4 5 6 7 周一至周日
			let date = new Date(dateStr);
			let week = date.getDay();
			if (week === 0) {
				week = 7;
			}
			let weekArray = [];
			for (let i = 0; i < this.infoData.week.length; i++) {
				weekArray.push(parseInt(this.infoData.week[i]));
			}
			// 最后判断是否在工作日周一至周五或周六
			if (weekArray.includes(week)) {
				return 0;
			} else {
				return 1;
			}
		},
		// "2025-05-01 9:00" 转成时间戳数据 s
		dateToTimestamp(date) {
			return +new Date(date) / 1000;
		},
		getRecordsList(data) {
			//获取当年当月打卡记录
			this.moxiPost(
				'/plugin/oa/user/clockin/check', { month: this.year + '-' + this.month.toString().padStart(2, '0') }, (res) => {
					this.recordsList = res.data;
					this.getCalendarDate();
					console.log(data);
					if (data) {
						this.activeIndex = this.calendarData.findIndex(item => item.label === data.label && !item.color);
					} else {
						if (this.fristLoad) {
							this.activeIndex = this.calendarData.findIndex(item => item.label === this.date && !item.color);
							this.fristLoad = false; // 只初始化一次
						} else this.activeIndex = this.calendarData.findIndex(item => item.label === 1 && !item.color)
					};
				}
			)
		},
		getInfo(data, index) {
			if (data.color) {
				if (index < Math.floor(this.calendarData.length / 2)) {
					this.dateUp(data);
				} else {
					this.dateDown(data);
				}
			} else {
				this.activeIndex = index;
			}
		},
		// 获取当前时间
		getNow() {
			let now = new Date();
			this.year = + now.getFullYear();
			this.month = + now.getMonth() + 1;
			this.date = + now.getDate();
			this.day = + now.getDay();
		},
		// 获取每个月的天数
		monthDay(month) {
			if ([1, 3, 5, 7, 8, 10, 12].includes(month)) {
				return 31;
			} else if ([4, 6, 9, 11].includes(month)) {
				return 30;
			} else if (month === 2) {
				//  判断当年是否为闰年
				if (
					(this.year % 4 === 0 && this.year % 100 !== 0) ||
					this.year % 400 === 0
				) {
					return 29;
				} else {
					return 28;
				}
			}
		},
		// 20250501 转成 2025-05-01 格式
		dateFormat(date) {
			// 转成string
			date = date.toString();
			let year = date.substring(0, 4);
			let month = date.substring(4, 6);
			let day = date.substring(6, 8);
			return `${year}-${month}-${day}`;
		},

		getCalendarDate() {
			// 获取当前月份一号星期几
			let firstDay = new Date(
				this.year + "-" + this.month + "-" + "01"
			).getDay();
			// 根据 weekFormat 重置表单
			if (this.weekFormat === 'sunFirst') {
				this.calendarData = [
					{ label: "日" },
					{ label: "一" },
					{ label: "二" },
					{ label: "三" },
					{ label: "四" },
					{ label: "五" },
					{ label: "六" },
				];
			} else {
				this.calendarData = [
					{ label: "一" },
					{ label: "二" },
					{ label: "三" },
					{ label: "四" },
					{ label: "五" },
					{ label: "六" },
					{ label: "日" },
				];
				firstDay = firstDay === 0 ? 6 : firstDay - 1;
			}
			let num = parseInt(firstDay);
			let nowDays = this.monthDay(this.month);
			let lastMonth = this.month - 1 > 0 ? this.month - 1 : 12;
			let lastDays = this.monthDay(lastMonth);
			//   循环添加上一个月数据
			for (let i = 0; i < num; i++) {
				this.calendarData.push({
					label: lastDays - num + i + 1,
					color: "#D1D1D1",
				});
			}
			// 循环添加当月数据
			// 时间排序，从小到大
			this.recordsList.sort((a, b) => a.work_start - b.work_start);
			// 为 must_clock 和 no_clock 创建映射
			const mustClockMap = new Map();
			const noClockMap = new Map();
			this.infoData.must_clock.forEach(dateStr => {
				const date = new Date(dateStr);
				const year = date.getFullYear();
				const month = date.getMonth() + 1;
				const day = date.getDate();
				if (year === this.year && month === this.month) {
					mustClockMap.set(day, true);
				}
			});
			this.infoData.no_clock.forEach(dateStr => {
				const date = new Date(dateStr);
				const year = date.getFullYear();
				const month = date.getMonth() + 1;
				const day = date.getDate();
				if (year === this.year && month === this.month) {
					noClockMap.set(day, true);
				}
			});
			for (let i = 0; i < nowDays; i++) {
				const day = i + 1;
				let itemData = { label: day };
				if (mustClockMap.has(day)) {
					itemData.type = 3;
				} else if (noClockMap.has(day)) {
					itemData.type = 2;
				}
				this.calendarData.push(itemData);
			}
			// 插入查询到用户打卡的数据
			for (let i = 0; i < this.recordsList.length; i++) {
				// 20250512 转成 时间戳 s
				const day = new Date(this.dateToTimestamp(this.dateFormat(this.recordsList[i].date)) * 1000).getDate();
				const item = this.calendarData.findIndex(item => item.label == day && !item.color);
				const type = this.workDay(this.year + "-" + this.month.toString().padStart(2, '0') + "-" + day.toString().padStart(2, '0'), this.recordsList[i].time_off_id);
				this.calendarData.splice(item, 1, {
					label: day,
					go: this.recordsList[i].start_status,
					off: this.recordsList[i].end_status,
					gotime: this.recordsList[i].work_start,
					offtime: this.recordsList[i].work_end,
					early: this.recordsList[i].early,
					late: this.recordsList[i].late,
					type: type,
					status: this.recordsList[i].status,
					start: this.recordsList[i].start,
					end: this.recordsList[i].end,
					date: this.recordsList[i].date,
				})
			}

			let month = new Date().getMonth() + 1;
			if (this.month == month) return;
			// 循环添加下一个月数据
			if (this.calendarData.length % 7 !== 0) {
				let surplusDay = 7 - (this.calendarData.length % 7);
				for (let i = 0; i < surplusDay; i++) {
					this.calendarData.push({ label: i + 1, color: "#D1D1D1" });
				}
			}
		},
		// 将日期调上
		dateUp(data = false) {
			this.month--;
			if (this.month <= 0) {
				this.year--;
				this.month = 12;
			}
			this.disableRightClick = false; // 初始化禁用右点击事件
			this.getRecordsList(data); // 获取员工这个月打卡信息
		},
		// 将日期调下
		dateDown(data = false) {
			if (this.disableRightClickFun()) return;
			this.month++;
			if (this.month > 12) {
				this.year++;
				this.month = 1;
			}
			this.getRecordsList(data); // 获取员工这个月打卡信息
			this.disableRightClickFun();
		},
	},
}
</script>

<style lang="scss" scoped>
@mixin flex($gap: 8px, $ju: space-between, $al: center, $fd: row, $wrap: nowrap) {
	display: flex;
	justify-content: $ju;
	align-items: $al;
	gap: $gap;
	flex-wrap: $wrap;
	flex-direction: $fd;
}

.clock-records {
	padding-top: 12px;

	.person-info {
		background-color: #fff;
		border-radius: var(--app-radius);
		@include flex;
		padding: 8px;
		font-size: 14px;
		color: #000;
		margin-bottom: 12px;

		.avatar {
			width: 48px;
			height: 48px;
			border-radius: 8px;
			overflow: hidden;
		}

		.info {
			margin: 0 auto 0 0;

			.name {
				font-weight: bold;
				margin-bottom: 4px;
			}

			.office {
				font-size: 12px;
			}
		}

		.more {
			@include flex(0px);
		}
	}

	.calendar {
		background-color: #fff;
		border-radius: var(--app-radius);
		padding: 24px 8px 8px;

		.calendar_top {
			@include flex(12px, center);

			.date {
				font-size: 13px;
			}
		}

		.week {
			margin: 18px 0 8px;
			@include flex(0, space-around);
			font-size: 10px;
			color: #B2B2B2;
			padding-bottom: 12px;
			border-bottom: 0.5px solid #DCDCDC;
		}

		.day {
			display: grid;
			grid-template-columns: repeat(7, 1fr);
			text-align: center;
			font-size: 14px;
			color: var(--app-color);

			.item {
				@include flex(0, center, center);

				.number {
					@include flex(0, center, center);
					border-radius: 50%;
					width: 36px;
					height: 36px;
					position: relative;

					.badge {
						position: absolute;
						top: 15%;
						right: 15%;
						width: 6px;
						height: 6px;
						background-color: var(--app-color);
						border-radius: 50%;
						font-size: 12px;
					}

					.badge_text {
						position: absolute;
						top: 0;
						right: 0;
						font-size: 8px;
						line-height: 8px;
					}


					&.active {
						background-color: var(--app-color);
						color: #fff !important;
						border-radius: 50%;
					}
				}
			}
		}
	}

	.show-status {
		background-color: #fff;
		border-radius: var(--app-radius);
		padding: 16px;
		margin-top: 12px;

		.illustrate {
			flex: 1;
			padding: 10px 15px;
			border-radius: var(--app-radius);
			overflow: hidden;
			font-size: 12px;
			color: #333;
			@include flex(4px, space-between, none, column);
			position: relative;

			&::before {
				content: "";
				position: absolute;
				top: 0;
				left: 0;
				width: 100%;
				height: 100%;
				background-color: var(--app-color);
				opacity: 0.2;
			}

			.item {
				@include flex(8px, normal);

				.badge {
					width: 8px;
					height: 8px;
					border-radius: 50%;
				}
			}
		}

		.showInfo {
			margin-top: 12px;
			position: relative;
			display: flex;
			flex-wrap: nowrap;

			.go-line {
				width: 8px;
				margin-right: 6px;
				@include flex(0, space-between, center, column);

				.circle {
					width: 6px;
					height: 6px;
					border: 2px solid #fff;
					border-radius: 99px;
				}

				.line {
					margin-left: 6px;
					margin-bottom: 2px;
					width: 8px;
					flex: 1;
					background-image: linear-gradient(#999999 60%, rgba(255, 255, 255, 0) 0%);
					background-position: left;
					background-size: 1px 8px;
					background-repeat: repeat-y;
				}
			}

			.item {
				font-size: 14px;

				&.go {
					@include flex(16px, space-between, normal, column);

					.go-item {
						position: relative;
						@include flex(4px, space-between, normal, column);

						.title {
							@include flex(0px, normal);

							.tag {
								font-size: 10px;
								padding: 2px 4px;
								border-radius: 4px;
							}
						}

						.gotime {
							@include flex(0px, normal);
						}

						.wifi {
							@include flex(4px, normal, center, row);
							color: #999;
						}
					}
				}
			}
		}
	}
}
</style>